package cn.ren.cloud.mq.consumer;

import cn.ren.cloud.domain.CourseMarket;
import cn.ren.cloud.domain.CourseUserLearn;
import cn.ren.cloud.dto.CourseOrderExtParamsDto;
import cn.ren.cloud.enums.GlobelExceptionEnum;
import cn.ren.cloud.exception.GlobalCustomException;
import cn.ren.cloud.service.ICourseMarketService;
import cn.ren.cloud.service.ICourseUserLearnService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateUtils;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 23508
 */
@Slf4j
@Component
@RocketMQMessageListener(
        consumerGroup = "course-handler-group",
        topic = "pay-order-topic",
        selectorExpression = "pay-order-tag",
        messageModel = MessageModel.BROADCASTING
)
public class CourseHandlerConsumer implements RocketMQListener<MessageExt> {

    private final ICourseUserLearnService courseUserLearnService;
    private final ICourseMarketService courseMarketService;


    public CourseHandlerConsumer(ICourseUserLearnService courseUserLearnService, ICourseMarketService courseMarketService) {
        this.courseUserLearnService = courseUserLearnService;
        this.courseMarketService = courseMarketService;
    }

    @Override
    public void onMessage(MessageExt messageExt) {

        // 1.参数校验
        byte[] body = messageExt.getBody();
        if (body.length == 0) {
            // 1.应该记录进入异常的次数，如果超过三次，那么应该通知管理员，手动处理
            log.error("支付后订单结果处理发生异常，异常信息为：消息信息为空！");
            throw new GlobalCustomException(GlobelExceptionEnum.GLOBE_EXCEPTION_ENUM_PARAM_ERROR);
        }

        CourseOrderExtParamsDto courseOrderExtParamsDto = JSON.parseObject(new String(body, StandardCharsets.UTF_8), CourseOrderExtParamsDto.class);
        String courseIds = courseOrderExtParamsDto.getCourseIds();
        Long loginId = courseOrderExtParamsDto.getUserId();
        String orderNo = courseOrderExtParamsDto.getOrderNo();
        List<Long> ids = Arrays.stream(courseIds.split(",")).map(Long::valueOf).collect(Collectors.toList());

        // 1.买过过期了  2.买过没过期  3.没买过
        Map<Long, CourseUserLearn> courseUserLearnMap = courseUserLearnService.selectByLoginId(loginId).stream().collect(Collectors.toMap(CourseUserLearn::getCourseId, courseUserLearn -> courseUserLearn));
        Map<Long, CourseMarket> courseMarketMap = courseMarketService.selectBatchIds(ids).stream().collect(Collectors.toMap(CourseMarket::getId, courseMarket -> courseMarket));
        for (Long id : ids) {
            CourseUserLearn courseUserLearn = courseUserLearnMap.get(id);
            CourseMarket courseMarket = courseMarketMap.get(id);
            Integer validDays = courseMarket.getValidDays();
            Date date = new Date();
            // 买过
            if (courseUserLearn != null) {
                // 没过期，续期
                if (CourseUserLearn.INTIME.equals(courseUserLearn.getState())) {
                    Date endTime = courseUserLearn.getEndTime();
                    // 使用日期+天数
                    courseUserLearn.setEndTime(DateUtils.addDays(endTime, validDays));
                } else {
                    // 过期，续订
                    courseUserLearn.setEndTime(DateUtils.addDays(date, validDays));
                }
                courseUserLearn.setState(CourseUserLearn.INTIME);
                courseUserLearnService.updateById(courseUserLearn);
            } else { // 没买过
                courseUserLearn = new CourseUserLearn();
                courseUserLearn.setLoginId(loginId);
                courseUserLearn.setStartTime(date);
                courseUserLearn.setEndTime(DateUtils.addDays(date, validDays));
                courseUserLearn.setState(CourseUserLearn.INTIME);
                courseUserLearn.setCourseId(id);
                courseUserLearn.setCourseOrderNo(orderNo);
                courseUserLearn.setCreateTime(date);
                courseUserLearnService.insert(courseUserLearn);
            }
        }
    }
}
